﻿Imports System.Text
Imports System.Collections.ObjectModel
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Media
Imports Microsoft.VisualStudio.Text
Imports Microsoft.VisualStudio.Text.Editor
Imports Microsoft.VisualStudio.Text.Formatting
Imports Microsoft.VisualStudio.Text.Tagging
Imports Microsoft.VisualStudio.Text.Adornments

Namespace Microsoft.VisualStudio.RegularExpression.BraceMatching
	Friend Class BraceMatchingPresenter
        Private textView As IWpfTextView
        Private WithEvents textViewCaret As ITextCaret
		'private IAdornmentLayer adornmentLayer;
		Private braceMatchers As IEnumerable(Of IBraceMatcher)
		Private tagger As ITextMarkerProviderFactory

		Friend Sub New(ByVal textView As IWpfTextView, ByVal braceMatcherProviders As IList(Of IBraceMatcherProvider), ByVal tagger As ITextMarkerProviderFactory)
            Me.braceMatchers = braceMatcherProviders.Select(Of IBraceMatcher)(Function(prov) prov.GetBraceMatcher(textView.TextSnapshot))
            Me.textView = textView
            Me.textViewCaret = textView.Caret

            Me.tagger = tagger
		End Sub

        Private Sub Caret_PositionChanged(ByVal source As Object, ByVal e As CaretPositionChangedEventArgs) Handles textViewCaret.PositionChanged
            RemoveAllAdornments(e.TextView.TextBuffer)
            If e.TextView.TextViewLines IsNot Nothing Then
                For Each braceMatcher As IBraceMatcher In braceMatchers
                    For Each spans As Tuple(Of SnapshotSpan, SnapshotSpan) In braceMatcher.GetBraceMatchingSpans(e.NewPosition.BufferPosition)
                        HighlightBounds(e.TextView.TextBuffer, spans.Item1)
                        HighlightBounds(e.TextView.TextBuffer, spans.Item2)
                    Next spans
                Next braceMatcher
            End If
        End Sub

		Private Sub RemoveAllAdornments(ByVal buffer As ITextBuffer)
			tagger.GetTextMarkerTagger(buffer).RemoveTagSpans(Function(span) True)
		End Sub

		Private Sub HighlightBounds(ByVal buffer As ITextBuffer, ByVal span As SnapshotSpan)
			   tagger.GetTextMarkerTagger(buffer).CreateTagSpan(span.Snapshot.CreateTrackingSpan(span.Span, SpanTrackingMode.EdgeExclusive), New TextMarkerTag("bracehighlight"))
		End Sub
	End Class
End Namespace